#include "app_porting.h"

#define CRACK_DEVICE RS232_DEVICE_5

//#define CRACK_TASK_DEBUG_ENABLE
//#define CRACK_TASK_ERROR_INFO

//#define CRACK_TIME_MEASURE
//#define CRACK_TESET_ENABLE

#define CRACK_IMPORTANT_INFO

#define CRACK_RECEIVE_TIMEOUT 3000
#define CRACK_TIME_OVER 3 //s
#define CRACK_RECEIVE_DATA_LEN 50
#define CRACK_SEND_DATA_LEN 50

typedef enum{
	YTPID_INFO_RECEIVED=0X11,
	YTPID_SN_SET=0X22,	
}YTPID_CMD_E;


CRACK_INFO_T g_crack_info;
uint8_t crack_deep;

uint8_t crack_timer;
uint8_t crack_receive_buf[CRACK_RECEIVE_DATA_LEN+INNER_PAD_LEN];
uint8_t crack_send_buf[CRACK_SEND_DATA_LEN+INNER_PAD_LEN];

static OS_EVENT *sg_sem_crack=NULL;
void sem_crack_init(void)
{
	sg_sem_crack=OSSemCreate(1);
	if(NULL==sg_sem_crack){
		//
	}	
}

void sem_crack_post(void)
{
	if(NULL!=sg_sem_crack){
		OSSemPost(sg_sem_crack);	
	}else{
		//
	}
}

void sem_crack_pend(void)
{
	INT8U err;
	if(NULL!=sg_sem_crack){
		OSSemPend(sg_sem_crack,0,&err);
	}else{
		//
	}
}


//{*,2.5,1S-A-250-4,-25,95,600,1000,740,1,-9,0,103,^}
int32_t crack_raw_parse(uint8_t *pstr)
{
	char *p;
	char *pvar1;
	char *pvar2;
	char *pvar3;
	
	p=strtok((char*)pstr,",");
	if(NULL==p){
		goto ERROR;
	}

	p=strtok(NULL,",");
	if(NULL==p){
		goto ERROR;
	}

	p=strtok(NULL,",");
	if(NULL==p){
		goto ERROR;
	}

	/*-25*/
	p=strtok(NULL,",");
	if(NULL==p){
		goto ERROR;
	}
	pvar1=p;

	/*95*/
	p=strtok(NULL,",");
	if(NULL==p){
		goto ERROR;
	}
	pvar2=p;

	p=strtok(NULL,",");
	if(NULL==p){
		goto ERROR;
	}

	p=strtok(NULL,",");
	if(NULL==p){
		goto ERROR;
	}

	p=strtok(NULL,",");
	if(NULL==p){
		goto ERROR;
	}

	p=strtok(NULL,",");
	if(NULL==p){
		goto ERROR;
	}

	p=strtok(NULL,",");
	if(NULL==p){
		goto ERROR;
	}

	p=strtok(NULL,",");
	if(NULL==p){
		goto ERROR;
	}

	/*103*/
	p=strtok(NULL,",");
	if(NULL==p){
		goto ERROR;
	}
	pvar3=p;

	sem_crack_pend();
	g_crack_info.dat1=atoi((char*)pvar1);;
	g_crack_info.dat2=atoi((char*)pvar2);;
	g_crack_info.dat3=atoi((char*)pvar3);;
	sem_crack_post();
	
#ifdef CRACK_TESET_ENABLE
	printf("crack_var={%d,%d,%d}\r\n",g_crack_info.dat1,g_crack_info.dat2,g_crack_info.dat3);
#endif
	return LS_SUCCESS;
	
ERROR:
	return LS_FAIL;	
}

static int16_t sg_current_depth;
void crack_current_depth_update(void)
{
	sem_crack_pend();
	sg_current_depth=g_crack_info.dat1;
	sem_crack_post();
}

void crack_current_depth_get(int16_t *pdepth)
{
	sem_crack_pend();
	*pdepth = sg_current_depth;
	sem_crack_post();
}

static int16_t sg_calibrate_depth;
void crack_calibrate_depth_set(int16_t depth)
{
	sem_crack_pend();
	sg_calibrate_depth=depth;
	sem_crack_post();
}

void crack_calibrate_depth_get(int16_t *pdepth)
{
	sem_crack_pend();
	*pdepth = sg_calibrate_depth;
	sem_crack_post();
}

uint8_t crack_deep_caculate(void)
{
	uint8_t depth=0;
	int16_t current_depth;
	int16_t calibrate_depth;

	crack_current_depth_get(&current_depth);
	crack_calibrate_depth_get(&calibrate_depth);

	if(current_depth<calibrate_depth){
#ifdef CRACK_IMPORTANT_INFO
		printf("[crack]depth=%d,current_depth=%d,calibrate_depth=%d\r\n",depth,current_depth,calibrate_depth);
#endif
		
		return depth;
	}

	depth=(uint8_t)((current_depth -calibrate_depth)/10);
	
#ifdef CRACK_IMPORTANT_INFO
	printf("[crack]depth=%d,current_depth=%d,calibrate_depth=%d\r\n",depth,current_depth,calibrate_depth);
#endif

	return depth;
}


void crack_calibrate(void)
{
	int16_t depth;

	crack_current_depth_get(&depth);	
	printf("[%s](%d)depth=%d\r\n",__FUNCTION__,__LINE__,depth);
	g_product_info.content.init_crack_depth=depth;
	product_info_write(&g_product_info);
	crack_calibrate_depth_set(depth);
}

void crack_task_init(void)
{
	sem_crack_init();
	crack_calibrate_depth_set(g_product_info.content.init_crack_depth);
}

void crack_task(void *pdata)
{	
	int32_t len;
#ifdef CRACK_TIME_MEASURE
	uint16_t orig_time;
#endif
#ifdef CRACK_TASK_DEBUG_ENABLE
	int32_t i;
#endif

	pdata  = pdata; 
#ifdef LIB_PRINTF_SUPPORT
	printf("[%s](%d) task created.\r\n",__FUNCTION__,__LINE__);
#endif		

	for(;;){		
#ifdef CRACK_TIME_MEASURE
		time_measure_start(&orig_time); 
#endif
		len=uart_get_buf(CRACK_DEVICE,crack_receive_buf,sizeof(crack_receive_buf),CRACK_RECEIVE_TIMEOUT);
		crack_receive_buf[len]=0;
		if(crack_timer>CRACK_TIME_OVER){
			crack_timer=0;
#ifdef CRACK_TASK_ERROR_INFO
			printf("[%s](%d)received timeover.\r\n",__FUNCTION__,__LINE__);
#endif		
			sem_crack_pend();
			memset(&g_crack_info,0,sizeof(CRACK_INFO_T));
			sem_crack_post();
		}
#ifdef CRACK_TASK_DEBUG_ENABLE
		if(len>0){
			printf("ytpid_received[%d]={",len);
			for(i=0;i<len;i++){
				printf("%c",crack_receive_buf[i]);
			}
			printf("}\r\n");
		}
#endif

		if(len<INNER_PAD_LEN){
#ifdef CRACK_TASK_ERROR_INFO
			printf("[%s](%d)received too short.\r\n",__FUNCTION__,__LINE__);
#endif		
			continue;
		}		

#ifdef CRACK_TIME_MEASURE
		printf("ytis_receive_times=%d(ms).\r\n",time_measure_get_ms(orig_time));	
//		continue;
#endif
		if(LS_SUCCESS==crack_raw_parse(crack_receive_buf)){
			crack_current_depth_update();
			crack_deep=crack_deep_caculate();
		}
		crack_timer=0;		
	} 
}

